#include "port.h"
#include "download.h"
#include "sm_types.h"
#include <pthread.h>
#include <semaphore.h>

#define LOADER_UPDATE_CLASS "com/smit/dvb/upgrade/SMDongleUpdateManager"

static char s_SN[25];
static char s_filePath[1024];
static pfLoaderCallback loaderCallbackFunc;
static pthread_t android_read_id;
static pthread_t android_appcmd_id;
static pthread_t update_start_id;
static sem_t g_sm1670_info_rdy_signal;
static sem_t g_update_info_signal;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

static DongleUpdateControl UpdateControl;
static DongleUpdateDongleType UpdateDongleType;
static unsigned long dwDownloadDataSize;

JavaVM		*gs_jvm = NULL;

/******************************************************************************
*                   function：ReadCommandOption()                *
*                   description：获得1670APP回复的信息
*                   write by:seven
*                   date:03-20-2014
******************************************************************************/
int loaderReadCommandOption(unsigned char *pbCommand, unsigned long dwBufferSize, unsigned long *pdwCommandLen)
{
	unsigned short wTag;
	unsigned short dwSize;
	unsigned short wCrc16;
	int ins =Q_NONE;
	int ret = 0;
	SM_Printf("loaderReadCommandOption() -  entry !!\n");
	ret = Sas_Update_Read(pbCommand, dwBufferSize, &dwSize);//sas没收到升级相关信息，则在此等待
	if(0 != ret) {
		SM_Printf_Error("loaderReadCommandOption() -  error!\n");
	}

	if (pbCommand[0] == 0x00 && pbCommand[1] == 0x00 && pbCommand[2] != 0x00)
	{
		dwSize -= 2;
		memmove(pbCommand, pbCommand + 2, dwSize);
	}

	if ((pbCommand[0] == STX))
	{	//Irdeto loader
		ins = Q_UPDATE_START;
		SM_Printf("loaderReadCommandOption() -  Dongle Irdeto update start!\n");
	}
	else if ((pbCommand[0] == SOH) && (pbCommand[1] == STX))
	{	//SSU loader
		ins = Q_UPDATE_START;
		SM_Printf("loaderReadCommandOption() -  Dongle SSU update start!\n");
	}
	else
	{
		//接收APP发过来的数据
		wTag = ASN_READ_UINT16(&pbCommand[0]);
		SM_Printf("loaderReadCommandOption() -  entry, wTag = %x!\n", wTag);

		switch (wTag){
		case SM1670_OPERATOR_REQUEST_TAG:
		case SM1670_UPDATE_INFO_REQUEST_TAG:
		case SM1670_DOWNLOAD_TRIGGER_TAG:
		case SM1670_DOWNLOAD_CORRUPTED_TAG:
			ins = Q_SSU_SM1670_INFO;
			break;
		default:
			break;
		}
	}

	*pdwCommandLen = dwSize;

	return ins;
}

/******************************************************************************
*                   function：SasReadTask()                *
*                   description：目前功能是获取1670回复的升级信息
*                   write by:seven
*                   date:03-20-2014
******************************************************************************/
int loaderSasReadTask()
{
	int dwOption;
	unsigned long rcvCommandLen;
	unsigned long dwSize;
	unsigned char rcvCommand[MAX_COMMAND_SIZE];
	memset(rcvCommand,1,sizeof(rcvCommand));

	while(1) {
		dwOption = loaderReadCommandOption(rcvCommand, MAX_COMMAND_SIZE, &rcvCommandLen);
		dwSize = 0;
		switch(dwOption) {
		case Q_UPDATE_START:
			memcpy(s_abCommand, rcvCommand, rcvCommandLen);
			s_abCommandLen = rcvCommandLen;
			memset(rcvCommand,0,sizeof(rcvCommand));
			sem_post(&g_update_info_signal);
			break;
		case Q_SSU_SM1670_INFO:
			memcpy(g_get_1670buf, rcvCommand, rcvCommandLen);
//			s_abCommandLen = rcvCommandLen;
			memset(rcvCommand,0,sizeof(rcvCommand));
			sem_post(&g_sm1670_info_rdy_signal);
			break;
		default:
			break;
		}
	}
}

/******************************************************************************
*                   function：GetCommandOption()                *
*                   description：向1670LOADER请求信息后,LOADER回复的信息解析
*                   write by:seven
*                   date:03-20-2014
******************************************************************************/
int loaderGetCommandOption(unsigned char *pbCommand, unsigned rcvSize)
{
	int ins =Q_NONE;
	unsigned short wTag;
	unsigned long dwSize;
	unsigned short wCrc16;
	int ret = 0;

	dwSize = rcvSize;

	if ((pbCommand[0] == SOH) && (pbCommand[1] == STX)) {
		//SSU Loader
		wTag = ASN_READ_UINT16(&pbCommand[2]);
		SM_Printf("loaderGetCommandOption() -  entry , wTag = %x\n",wTag);
		switch (wTag) {
		case TF_DOWNLOAD_INFO_REQUEST:
			ins = Q_SSU_INFO_REQUEST;
			break;
		case TF_DOWNLOAD_DATA_REQUEST:
			ins = Q_SSU_DATA_REQUEST;
			break;
		case DOWNLOAD_FINISH_TAG:
			ins = Q_SSU_FINISH;
			break;
		case DOWNLOAD_GET_DATE_TIME_TAG:
			ins = Q_SSU_DOWNLOAD_DATE_TIME;
			break;
		case CRC_CHECK:
			SM_Printf("loaderGetCommandOption() -  CRC_CHECK.\n");
			break;
		default:
			break;
		}
	}
	else if ((pbCommand[0] == STX)){
		//Irdeto CA
		wTag = pbCommand[1];
		switch (wTag){
		case CMD_STB_TIME_REQUEST:
			ins = Q_TIME;
			break;
		case CMD_STB_DATA_REQUEST:
			ins = Q_DATA;
			break;
		case CMD_FILE_SIZE:
			ins = Q_SIZE;
			break;
		case CMD_REOPTION_LENGTH:
			ins = Q_REOPTION;
			break;
		case CMD_MIXTERM_VER:
			ins = Q_MIXTERM_VER;
			break;
		case CMD_MANUFACTURER_TYPE_HWVER:
			ins = Q_MANUFACTURER_TYPE_HWVER;
			break;
		case CMD_DATA_ERROR:
			ins = Q_DOWNLOAD_ERROR;
			break;
		case CMD_DATA_TRANSFER_END:
			ins = Q_TRANSFER_END;
			break;
		case CMD_STB_DL_OK:
		case CMD_STB_ERROR:
			ins = Q_DOWNLOAD_OK;
			break;
		default:
			break;
		}
	}
	
	return ins;
}

long loaderUpdateTask(void)
{
	int dwOption;
	unsigned long dwCommandLen;
	unsigned long dwSize;
	unsigned long dwOffset;
	unsigned long dwLength;
	unsigned long dwType;
	unsigned long dwhwVer;
	unsigned short wModuleId;
	unsigned short wBlockNumber;
	unsigned long dwErrorCode;
	unsigned short bModuleCount;
	unsigned char bRate;
	char *pErrorName;
	char *pbDescription;

	SM_Printf("loaderUpdateTask() -  entry , loaderUpdateTask start !!\r\n");
	
	while (1) {
		sem_wait(&g_update_info_signal);
		SM_Printf("loaderUpdateTask() -  info ,sem_wait g_update_info_signal\r\n");

		pthread_mutex_lock(&mutex);
		if (!UpdateControl.SdlOpen)
			pthread_cond_wait(&cond, &mutex);
		SM_Printf("loaderUpdateTask() -  info ,pthread_cond_wait ok\r\n");
		pthread_mutex_unlock(&mutex);

		dwOption = loaderGetCommandOption(s_abCommand, s_abCommandLen);//s_abCommand为包头+TLV+包尾的全部数据
		dwSize = 0;

		SM_Printf("loaderUpdateTask() -  info ,g_update_info_signal dwOption = %d\r\n",dwOption);
		switch (dwOption)
		{
		case Q_TIME:
			SetLoaderType(IRDETO_LOADER);
			SM_Printf("[Mixterm] Get current time error\r\n");
			break;
		case Q_DATA:
			dwLength = HAL_READ_UINT16(&s_abCommand[2]);
			dwOffset = HAL_READ_UINT32(&s_abCommand[4]);
			dwSize = GetDownloadData((char*)s_abCommand, dwOffset, dwLength) ;
			if(dwDownloadDataSize >= dwOffset+dwLength && dwSize == dwLength) {
			//	bRate = (unsigned char)((dwOffset + dwLength) * 100 / dwDownloadDataSize);
			//	ShowDownloadSchedule(bRate);
			} else {
				SM_Printf_Error("loaderUpdateTask() -  error , Read data from file error, File size:0x%08lx, Offset:0x%08lx, Length:0x%08lx\n",dwDownloadDataSize,dwOffset,dwLength);
			}
			break;

		case Q_SIZE:
			HAL_WRITE_UINT32(s_abPayload, dwDownloadDataSize);
			IrdetoAssembleCommand(CMD_FILE_SIZE, s_abPayload, 4, s_abCommand, &dwSize);
			break;

		case Q_REOPTION:
			memset(s_abPayload, 0, 4);
			IrdetoAssembleCommand(CMD_REOPTION_LENGTH, s_abPayload, 4, s_abCommand, &dwSize);
			break;

		case Q_MIXTERM_VER:
			strncpy((char*)s_abPayload, bpMixtermVer, 5);
			IrdetoAssembleCommand(CMD_MIXTERM_VER, s_abPayload, 5, s_abCommand, &dwSize);
			break;

		case Q_MANUFACTURER_TYPE_HWVER:
			dwType = HAL_READ_UINT32(&s_abCommand[6]);
			dwhwVer = HAL_READ_UINT32(&s_abCommand[10]);
			SM_Printf("loaderUpdateTask() -  info ,  Manufacturer Code: %c%c%c%c Type:%ld Hardware Version:%ld\n", (char)s_abCommand[5],
					               (char)s_abCommand[4], (char)s_abCommand[3], (char)s_abCommand[2], dwType, dwhwVer);
			break;
		case Q_DOWNLOAD_ERROR:
			dwErrorCode = ASN_READ_UINT32(&s_abCommand[2]);
			if (dwErrorCode == 0) {
				SM_Printf_Error("loaderUpdateTask() -  info , Key or variant download complete!");
			} else {
				GetDownloadErrorInfo(dwErrorCode, &pErrorName, &pbDescription);
				SM_Printf_Error("loaderUpdateTask() -  error ,  Error code: 0x%08lx %s\r\n", dwErrorCode, pErrorName);
				SM_Printf_Error("loaderUpdateTask() -  info , [Mixterm] %s\r\n", pbDescription);
				SM_Printf_Error("loaderUpdateTask() -  Error code: 0x%08lx %s", dwErrorCode, pErrorName);
			}
			break;
		case Q_TRANSFER_END:
			bRate = 100;
			//ShowDownloadSchedule(bRate);
			//java begin
			loaderSendUpdateProcessMsg(MSG_UPDATE_FINISH);
			//java end
			SM_Printf("loaderUpdateTask() -  info ,[Mixterm] Downloading successfully\r\n");
			break;
		case Q_SSU_INFO_REQUEST:
			SM_Printf("loaderUpdateTask() -  info ,Q_SSU_INFO_REQUEST\r\n");
			SetLoaderType(SSU_LOADER);

			if (SsuDownloadFileInit() == 0) {
				dwErrorCode = SsuGetDii(s_abPayload, &dwLength);
				if (dwErrorCode == 0) {
                    SsuAssembleMessage(DOWNLOAD_INFO_RESPONE, s_abPayload, dwLength, s_abCommand, &dwSize);
                    SM_Printf("loaderUpdateTask() -  info ,[Mixterm] dwSize =%lu\r\n",dwSize);
					//bModuleCount = s_abPayload[DII_MODULE_COUNT_INDEX];
					bModuleCount  = COM_PATIBILITY_DES_INDEX;
					bModuleCount += (2 + ASN_READ_UINT16(&s_abPayload[bModuleCount]));
					bModuleCount  = ASN_READ_UINT16(&s_abPayload[bModuleCount]);
					dwDownloadDataSize = GetDownloadDataLength();
				} else {
					SM_Printf_Error("loaderUpdateTask() -  info ,[Mixterm] Read DII data from SDL file error\r\n");
				}
			} else {
				SM_Printf_Error("loaderUpdateTask() -  info ,[Mixterm] SDL file is destructed\r\n");
			}
			break;

		case Q_SSU_DATA_REQUEST:
			wModuleId = s_abCommand[REQUEST_MESSAGE_DDMID_INDEX+1];		//只读DDM低位数据；高位另有用途，会造成勿扰
			wBlockNumber = ASN_READ_UINT16(&s_abCommand[REQUEST_MESSAGE_DDBID_INDEX]);
			SM_Printf("loaderUpdateTask() -  info ,[Mixterm] wModuleId = %x\r\n",wModuleId);
			SM_Printf("loaderUpdateTask() -  info ,[Mixterm] wBlockNumber = %x\r\n",wBlockNumber);
			dwErrorCode = SsuGetDdb(s_abPayload, &dwLength, wModuleId, wBlockNumber);
			SM_Printf("loaderUpdateTask() -  info ,[Mixterm] dwLength = %lx\r\n",dwLength);
			if (dwErrorCode == 0) {
				SsuAssembleMessage(DOWNLOAD_DATA_RESPONE, s_abPayload, dwLength, s_abCommand, &dwSize);
				SM_Printf("loaderUpdateTask() -  info ,[Mixterm] dwSize = %lx\r\n",dwSize);
				if ( bModuleCount > 0) {
					bRate = ((wModuleId + 1) * 100) / bModuleCount;
					ShowDownloadSchedule(bRate);
				}
			} else {
				SM_Printf_Error("loaderUpdateTask() -  error ,[Mixterm] Read DDB %d of DDM %d data from SDL file error\r\n", wBlockNumber, wModuleId);
			}
			break;

		case Q_SSU_FINISH:
			dwErrorCode = ASN_READ_UINT32(&s_abCommand[32]);
			SM_Printf_Error("loaderUpdateTask() -  error ,[Mixterm] dwErrorCode = %lx\r\n", dwErrorCode);
			if (dwErrorCode == DOWNLOAD_FINISH) {
				//java begin
				loaderSendUpdateProcessMsg(MSG_UPDATE_FINISH);
				//java end
				SM_Printf("loaderUpdateTask() -  info ,[Mixterm] Downloading successfully\r\n");
				SM_Printf("loaderUpdateTask() -  info ,[Mixterm] DOWNLOAD_FINISH\r\n");
			} else {
				GetDownloadErrorInfo(dwErrorCode, &pErrorName, &pbDescription);
				SM_Printf_Error("loaderUpdateTask() -  error ,[Mixterm] Error code: 0x%08lx %s\r\n", dwErrorCode, pErrorName);//privateDataByte�д�����
				SM_Printf_Error("loaderUpdateTask() -  info ,[Mixterm] %s\r\n", pbDescription);
			}
			break;

		case Q_SSU_DOWNLOAD_DATE_TIME:
			GetMyTime((char*)s_abPayload);
			SsuAssembleMessage(DOWNLOAD_DATE_TIME_RESP_SUB_TAG, s_abPayload, 5, s_abCommand, &dwSize);
			break;

		default:
			dwSize =0;
			break;
		}

		SM_Printf("loaderUpdateTask() -  info ,[Mixterm] Write dwSize = %lx\r\n", dwSize);
		dwErrorCode = ModuleWriteCommand(s_abCommand, dwSize);
		if (dwErrorCode != dwSize) {
			SM_Printf_Error("loaderUpdateTask() -  error ,[Mixterm] Write data error (0x%lx -> 0x%lx)\r\n", dwSize,  dwErrorCode);
		}
	}
	return 0;
}

/******************************************************************************
*                   function：APK_Send_Info()                *
*                   description：发送信息给1670
*                   write by:seven
*                   date:03-20-2014
******************************************************************************/
int loaderCMDResponse(unsigned short tag,unsigned char *responseInfo)
{
	unsigned long responseInfoLen;
	unsigned char message[MAX_COMMAND_SIZE];
	unsigned long dwSize;
	unsigned long dwErrorCode;

	memset(message,0,sizeof(message));//////
	responseInfoLen = strlen(responseInfo);
	AppAssembleMessage(tag, responseInfo, responseInfoLen, message, &dwSize);
	SM_Printf("loaderCMDResponse() -  info , responseInfoLen =%lu\r\n", responseInfoLen);
	SM_Printf("loaderCMDResponse() -  info , dwSize =%lu\r\n", dwSize);

	dwErrorCode = ModuleWriteCommand(message, dwSize);
	if (dwErrorCode != dwSize) {
		SM_Printf_Error("loaderCMDResponse() -  error ,Write APK_Send_Info error (0x%lx -> 0x%lx)\r\n", dwSize,  dwErrorCode);
	}
	return dwErrorCode;
}

/******************************************************************************
*                   function：AppCmdTask()                *
*                   description：APP信息处理
*                   write by:seven
*                   date:03-20-2014
******************************************************************************/
void loaderCMDTask(void)
{
	unsigned short tag = 0;
	unsigned char *requestInfo = NULL;
	unsigned char responseInfo[MAX_COMMAND_SIZE];
	int requestInfoLen = 0;

	SM_Printf("loaderCMDTask() -  entry , start !!\r\n");
	while (1) {
		sem_wait(&g_sm1670_info_rdy_signal);
		requestInfo = &g_get_1670buf[6];
		requestInfoLen = strlen(requestInfo);
		tag = ASN_READ_UINT16(&g_get_1670buf[0]);
		SM_Printf("loaderCMDTask() -  info , tag = 0x%x \r\n",tag);
		SM_Printf("loaderCMDTask() -  info , requestInfoLen =%d\r\n",requestInfoLen);
		SM_Printf("loaderCMDTask() -  info , requestInfo =%c\r\n",g_get_1670buf[6]);

		switch (tag) {
		case SM1670_OPERATOR_REQUEST_TAG:
			//获取营运商
			//java begin
			loaderSendUpdateFirmWareInfo(requestInfo);
			//java end
			memset(requestInfo,0,requestInfoLen);
			requestInfoLen = 0;
			break;
		case SM1670_UPDATE_INFO_REQUEST_TAG:
			//升级信息
			SM_Printf("loaderCMDTask() -  info ,SM1670_UPDATE_INFO_REQUEST_TAG----g_get_1670buf[6] = %x\r\n",g_get_1670buf[6]);
			if (requestInfoLen == 12) {
				UpdateControl.CAType = TRUE;
			} else {
				UpdateControl.CAType = FALSE;
			}
			//java begin
			loaderSendUpdateFirmWareInfo(requestInfo);
			//java end
			memset(requestInfo,0,requestInfoLen);
			requestInfoLen = 0;
			break;
		case SM1670_DOWNLOAD_TRIGGER_TAG:
			//触发升级
			SM_Printf("loaderCMDTask() -  info ,SM1670_DOWNLOAD_TRIGGER_TAG----g_get_1670buf[6] = %x\r\n",g_get_1670buf[6]);
			if (TRIGGER_NO_DOWNLOAD_TAG == g_get_1670buf[6]) {
				SM_Printf("loaderCMDTask() -  info ,SM1670_DOWNLOAD_TRIGGER_TAG TRIGGER_NO_DOWNLOAD_TAG\r\n");
			} else if (TRIGGER_START_RINGHTNOW_TAG == g_get_1670buf[6]) {
				if (strlen(s_filePath) > 0) {
					DownloadDataInit((char*)s_filePath);
					pthread_mutex_lock(&mutex);

					if (UpdateControl.CAType == FALSE) {
						*responseInfo = (unsigned char)((0x02)&0xFF);
						loaderCMDResponse(SM1670_DOWNLOAD_STATUS_TAG,responseInfo);
						dwDownloadDataSize = GetDownloadDataLength();
						SM_Printf("loaderCMDTask() -  info ,dwDownloadDataSize =0x%08lx\r\n",dwDownloadDataSize);
					}

					if (!UpdateControl.SdlOpen)
						pthread_cond_signal(&cond);
					UpdateControl.SdlOpen = TRUE;

					SM_Printf("loaderCMDTask() -  info ,SM1670_DOWNLOAD_TRIGGER_TAG pthread_cond_signal()\r\n");
					pthread_mutex_unlock(&mutex);

				}
			}
			break;
		case SM1670_DOWNLOAD_CORRUPTED_TAG:
			{
				unsigned char* RequestInfo = UpdateDongleType.IrdeoType;
				SM_Printf("loaderCMDTask() -  entry ,SM1670_DOWNLOAD_CORRUPTED_TAG enter\r\n");
				//java begin
				//	loaderSendUpdateFirmWareInfo(requestInfo);
				//java end

				if (strlen(s_filePath) > 0){
					DownloadDataInit((char*)responseInfo);
					*responseInfo = (unsigned char)((0x02)&0xFF);
					loaderCMDResponse(SM1670_DOWNLOAD_STATUS_TAG,responseInfo);

					sem_post(&g_update_info_signal);
					pthread_mutex_lock(&mutex);
					if (!UpdateControl.SdlOpen)
						pthread_cond_signal(&cond);
					UpdateControl.SdlOpen = TRUE;
					dwDownloadDataSize = GetDownloadDataLength();
					SM_Printf("loaderCMDTask() -  info ,dwDownloadDataSize =0x%08lx\r\n",dwDownloadDataSize);
					SM_Printf("loaderCMDTask() -  info ,SM1670_DOWNLOAD_TRIGGER_TAG pthread_cond_signal()\r\n");
					pthread_mutex_unlock(&mutex);
				}
			}
			break;
		default:
			break;
		}
	}
}

int loaderTaskParams()
{

	SM_Printf("loaderTaskParams() -  entry!\r\n");
	sem_init(&g_sm1670_info_rdy_signal,0,0);
	sem_init(&g_update_info_signal,0,0);
	pthread_mutex_init(&mutex,NULL);
	pthread_cond_init(&cond,NULL);

	UpdateControl.CAType = FALSE;	//FALSE->Irdeto;TURE->SSU
	UpdateControl.SdlOpen = FALSE;
	UpdateDongleType.IrdeoType = "0041";
	UpdateDongleType.SSUType = "0042";

	return 0;
}

int loaderTaskUnInit()
{
	android_read_id = 0;
	update_start_id = 0;
	android_appcmd_id = 0;
	sem_destroy(&g_sm1670_info_rdy_signal);
	sem_destroy(&g_update_info_signal);
	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&cond);

	return 0;
}

int loaderTaskInit()
{
	unsigned short tag = 0;
	SM_Printf("loaderTaskInit() - entry!! android_read_id=%ld  android_appcmd_id=%ld\r\n",android_read_id,android_appcmd_id);

	if (android_read_id == 0) {
		loaderTaskParams();
		if (pthread_create(&android_read_id, NULL, (void *)loaderSasReadTask, NULL)) {
			SM_Printf_Error("loaderTaskInit() -  error, loaderSasReadTask create error!\r\n");
			return -1;
		}
	}

	if (android_appcmd_id == 0) {
		if (pthread_create(&android_appcmd_id, NULL, (void *)loaderCMDTask, NULL)) {
			SM_Printf_Error("loaderTaskInit() -  error, loaderCMDTask Create ERROR\r\n");
			return -1;
		}
	}
	//	pthread_join(android_read_id,NULL);
	//	pthread_join(android_appcmd_id,NULL);

	if (update_start_id == 0) {
		if (pthread_create(&update_start_id, NULL, (void *)loaderUpdateTask, NULL)) {
			SM_Printf_Error("loaderTaskInit() -  error ,loaderUpdateTask Create ERROR\r\n");
			return -1;
		}
	}
//	if (pthread_join(update_start_id,NULL) != 0){
//		SM_Printf("update_start_id join error!!!\r\n");
//	} else {
//		SM_Printf("update_start_id join ok!!!\r\n");
//	}
	SM_Printf("loaderTaskInit() -  return!!\r\n");
	return tag;
}

/////////////////////////////////////////////////////////////////////////////

int loaderRegistorCallback(pfLoaderCallback pfCb)
{
	loaderCallbackFunc = pfCb;
	return 0;
}

int loaderSendUpdateFirmWareInfo(unsigned char *id)
{
	int ret = -1;
	void *Pparam = NULL;
	Pparam=id;
	if(loaderCallbackFunc)
		ret = loaderCallbackFunc(DVB_CB_TYPE_UPDATE, MSG_UPDATE_REQUEST_FIRMWARE, Pparam);
	return 0;
}

int loaderSendUpdateProcessMsg(int type)
{
	int ret = -1;
	if(loaderCallbackFunc)
		ret = loaderCallbackFunc(DVB_CB_TYPE_UPDATE, type, NULL);
	return ret;
}

void loaderSetFirmwareInfo(char* sn, char* filePath)
{
	unsigned short tag = 0;
	int responseInfoLen = 1024;
	unsigned char responseInfo[MAX_COMMAND_SIZE];
	SM_Printf_Error("loaderSetFirmwareInfo() - sn:%s, filePath=%s\r\n", sn, filePath);
	if (sn == NULL || filePath == NULL)
		return;
	
	memcpy(s_SN, sn, strlen(sn));
	memcpy(s_filePath, filePath, strlen(filePath));

	tag = ASN_READ_UINT16(&g_get_1670buf[0]);
	switch (tag) {
		case SM1670_OPERATOR_REQUEST_TAG:
			break;
		case SM1670_UPDATE_INFO_REQUEST_TAG:
			if (strlen(sn) > 0) {
				loaderCMDResponse(SM1670_UPDATE_INFO_RESPONSE_TAG,s_SN);
			} else {
				SM_Printf_Error("loaderSetFirmwareInfo() -  error ,SM1670_UPDATE_INFO_REQUEST_TAG error\r\n");
			}
			break;
		default:
			break;
	}
	
}

int loaderInit(pfLoaderCallback pfCb)
{
	int ret = 0;
	loaderRegistorCallback(pfCb);
	ret = loaderTaskInit();
	return ret;
}

/*
static int loaderRegisterMethods(JNIEnv *env)
{
	jclass clazz;
	
	clazz = (*env)->FindClass(env, LOADER_UPDATE_CLASS);
	if (clazz == NULL) 
	{
		SM_Printf_Error("loaderRegisterMethods() - unable to find class\r\n'");
		return JNI_FALSE;
	}
	
	if ((*env)->RegisterNatives(env, clazz, s_Methods, sizeof(s_Methods)/sizeof(s_Methods[0])) < 0) {
		SM_Printf_Error("loaderRegisterMethods() - RegisterNatives failed\r\n'");
		if ((*env)->ExceptionCheck(env))//clear exception
		{
			(*env)->ExceptionClear(env);
			SM_Printf_Error("loaderRegisterMethods() - found exception, native method may not founded int JAVA\r\n");
		}
		(*env)->DeleteLocalRef(env, clazz);
		return JNI_FALSE;
	}
	(*env)->DeleteLocalRef(env, clazz);
	return JNI_TRUE;
}

int Loader_JNI_OnLoad(JavaVM *vm, void *reserved)
{
	JNIEnv *jenv = NULL;
	jint    result = -1;
	if ((*vm)->GetEnv(vm, (void **)&jenv, JNI_VERSION_1_4) != JNI_OK) {
		SM_Printf_Error("Loader_JNI_OnLoad() - error, ERROR: GetEnv failed\n");
		goto fail;
	}
	
	if((*jenv)->GetJavaVM(jenv,&gs_jvm) != JNI_OK) {
		DVB_DebugOutput(DVB_DEBUG_LEVEL_ERROR, "JNI_OnLoad() - ERROR: GetJavaVM failed\n");
		goto fail;
	}
	
	if (loaderRegisterMethods(jenv) < 0) {
		SM_Printf_Error("Loader_JNI_OnLoad() - error, ERROR: GetEnv failed\n");
	}

	result = JNI_VERSION_1_4;

fail:
	return result;
}
void Loader_JNI_OnUnload(JavaVM *vm, void *reserved)
{
	JNIEnv *jenv = NULL;
	if ((*vm)->GetEnv(vm, (void **)&jenv, JNI_VERSION_1_4) != JNI_OK) {
		SM_Printf_Error("Loader_JNI_OnUnload() - error, ERROR: GetEnv failed\n");
	}
	jenv = NULL;
}

*/




